/*
  S.M.A.C.K - An operating system kernel
  Copyright (C) 2010,2011 Mattias Holm and Kristian Rietveld
  For licensing and a full list of authors of the kernel, see the files
  COPYING and AUTHORS.
*/

#ifndef KERNEL__DEVICE_H
#define KERNEL__DEVICE_H

#include <stddef.h>
#include <sys/types.h>

#define MAX_DEVICES 32

// TODO: Move to common file
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2

typedef enum {
  DEV_CHAR,
  DEV_BLOCK
} dev_kind_t;

typedef enum {
  DEV_SERIAL = 0,
  DEV_SDCARD,
  DEV_FRAMEBUF,
  DEV_RAMDISK,
} dev_major_t;

typedef unsigned dev_minor_t;
typedef struct dev_t dev_t;

typedef size_t (*dev_read_fn_t)(dev_t *dev, dev_minor_t minor, void *buff, size_t nbytes);
typedef size_t (*dev_write_fn_t)(dev_t *dev, dev_minor_t minor, const void *buff, size_t nbytes);
typedef off_t (*dev_seek_fn_t)(dev_t *dev, dev_minor_t minor, off_t offset, int whence);
typedef int (*dev_open_fn_t)(dev_t *dev, dev_minor_t minor);
typedef int (*dev_close_fn_t)(dev_t *dev, dev_minor_t minor);
typedef int (*dev_ioctl_fn_t)(dev_t *dev, dev_minor_t minor, uint32_t request, uint32_t param);


typedef struct {
  dev_read_fn_t read;
  dev_write_fn_t write;
  dev_seek_fn_t seek;
  dev_open_fn_t open;
  dev_close_fn_t close;
  dev_ioctl_fn_t ioctl;
} dev_ops_t;

struct dev_t {
  dev_kind_t type;
  char *name;
  char *mountname;
  dev_major_t major;
  dev_minor_t minor_count;
  dev_ops_t *ops;
};

void dev_init(void);
void dev_register(dev_major_t major, dev_t *dev);
dev_t* dev_find(dev_major_t major);

size_t dev_read(dev_t *dev, dev_minor_t minor, void *buff, size_t nbytes);
size_t dev_write(dev_t *dev, dev_minor_t minor, const void *buff, size_t nbytes);
off_t dev_seek(dev_t *dev, dev_minor_t minor, off_t offset, int whence);
int dev_open(dev_t *dev, dev_minor_t minor);
int dev_close(dev_t *dev, dev_minor_t minor);
int dev_ioctl(dev_t *dev, dev_minor_t minor, uint32_t request, uint32_t param);

#endif  /* !KERNEL__DEVICE_H */
